package com.project.srtp.secure.service.impl;

import com.project.srtp.secure.dto.req.BusinessOperationReqDTO;
import com.project.srtp.secure.Enum.OperationType;
import com.project.srtp.secure.model.AuditLogDO;
import com.project.srtp.secure.dao.mapper.AuditLogMapper;
import com.project.srtp.secure.service.AuditLogService;
import com.project.srtp.secure.util.CryptoUtil;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;

import java.security.NoSuchAlgorithmException;
import java.security.NoSuchProviderException;
import java.time.Instant;

/**
 * @author 曹行阳
 * @version 0.1
 * @date 2025/6/11 11:19
 */

@Service
@RequiredArgsConstructor
public class AuditLogServiceImpl implements AuditLogService {

    private final AuditLogMapper auditLogMapper;
    private final CryptoUtil cryptoUtils;

    @Override
    public AuditLogDO createVerifiableLog(BusinessOperationReqDTO reqDTO) throws NoSuchAlgorithmException, NoSuchProviderException {
        long timestamp = Instant.now().toEpochMilli();

        // Step 1: Generate Operation Fingerprint
        String nonce = cryptoUtils.generateNonce(timestamp, reqDTO.getUserRole(), reqDTO.getUserId());
        String fingerprint = cryptoUtils.generateBlake3Fingerprint(reqDTO, nonce);

        // Step 2: Build Commitment and Proofs
        String commitment = cryptoUtils.generatePedersenCommitment(fingerprint);
        String rangeProof = cryptoUtils.generateRangeProof(reqDTO.getQuantity());
        String blsSignature = cryptoUtils.generateEcdsaSignature(commitment, rangeProof);

        // Step 3: Construct and Save the Verifiable Log
        AuditLogDO logDO = AuditLogDO.builder()
                .userId(reqDTO.getUserId())
                .opType(OperationType.valueOf(reqDTO.getOpType()))
                .value(reqDTO.getValue())
                .timestamp(timestamp)
                .operationFingerprint(fingerprint)
                .pedersenCommitment(commitment)
                .rangeProof(rangeProof)
                .blsSignature(blsSignature)
                .createdAt(Instant.now())
                .build();

        auditLogMapper.insert(logDO);
        return logDO;
    }
}
